package com.polaris.live.ui.login.verify

import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.view.KeyEvent
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.core.os.bundleOf
import com.blankj.utilcode.util.ColorUtils
import com.blankj.utilcode.util.StringUtils
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import com.polaris.live.R
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.constant.BizEventConst
import com.polaris.live.common.constant.PagConst.BTN_GOOGLE_PAG
import com.polaris.live.common.event.EventMessage
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.ImmersionBarBuilder
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.constant.EventConst
import com.polaris.live.constant.TrackEventConst.EVENT_CODE_UV
import com.polaris.live.constant.TrackEventConst.EVENT_LOGIN_GOOGLE_CODE_UC
import com.polaris.live.constant.TrackEventConst.EVENT_SEND_CODE_UC
import com.polaris.live.constant.TrackEventConst.TRACK_PAGE
import com.polaris.live.databinding.ActivityVerifyBinding
import com.polaris.live.interface_bag.TextWatcherAdapter
import com.polaris.live.manager.DomainManager
import com.polaris.live.translation.R.string
import com.polaris.live.ui.login.BaseGoogleLoginActivity
import com.polaris.live.ui.main.activity.MainActivity
import com.polaris.live.utils.CommonUtils
import com.polaris.live.utils.TrackHelper
import com.polaris.live.utils.UserUtils
import com.polaris.live.utils.getBooleanOrString
import com.polaris.live.utils.postEvent
import com.polaris.live.viewmodel.VerifyViewModel
import org.greenrobot.eventbus.EventBus

/**
 * 验证码页面
 *
 * @author Created by 半仙 on 2023/8/9/009 17:56
 */
class VerifyActivity : BaseGoogleLoginActivity<VerifyViewModel, ActivityVerifyBinding>() {

    private var mIsTiming = false // 判断 定时器是否在在跑
    private var mIsInput = false // 判断 10内用户有没有输入验证码

    private var mPhoneNumber: String? = null
    private var mAreaCode: String? = null
    private var mGmail: String? = null
    private var mGoogleValidate: String? = null
    private var mIsBind = false

    private var mIsPlay = false

    override fun ImmersionBarBuilder.buildImmersionBar() {
        setTitleBar(mBinding.bvTitle)
    }

    override fun initView(savedInstanceState: Bundle?) {
        super.initView(savedInstanceState)

        mPhoneNumber = intent.getStringExtra("phoneNumber")
        mAreaCode = intent.getStringExtra("areaCode")
        mGmail = intent.getStringExtra("gmail")
        mGoogleValidate = intent.getStringExtra("googleValidate")
        mIsBind = intent.getBooleanOrString("bind", false)

        initView()
        initObserve()

        sendVerifyCode(CacheUtil.isSentVerifyCode(resolveCurrentNumber(), getSendType()))

        TrackHelper.trackActivity(this, EVENT_CODE_UV, TRACK_PAGE)
        setInputBack()
    }

    private fun initView() {
        mBinding.verifyPhoneNumber.text = resolveCurrentNumber()

        if (mIsBind) {
            mBinding.tvTitleLogin.text = if (!mGmail.isNullOrEmpty()) {
                StringUtils.getString(string.bind_gmail)
            } else {
                StringUtils.getString(string.bind_phone)
            }

            mBinding.btnBind.setOnSingleClickListener {
                triggerLogin()
            }

            mBinding.selectGoogleLogin.visibility = View.GONE
            mBinding.btnBind.visibility = View.VISIBLE
        } else {
            mBinding.selectGoogleLogin.apply {
                path = BTN_GOOGLE_PAG
                setRepeatCount(-1)
            }
            mBinding.selectGoogleLogin.setOnSingleClickListener {
                TrackHelper.trackActivity(this, EVENT_LOGIN_GOOGLE_CODE_UC)
                gotoGoogleLogin()
            }
        }

        mBinding.verifyTime.text = StringUtils.getString(string.verify_again)
        mBinding.verifyTime.alpha = 1.0f

        mBinding.verifyTime.setOnSingleClickListener {
            TrackHelper.trackActivity(this, EVENT_SEND_CODE_UC)
            if (!mIsTiming) {
                sendVerifyCode()
            }
        }

        verifyEdit()
    }

    private fun initObserve() {
        mViewModel.countdownLiveData.observe(this) { millisUntilFinished ->
            if (millisUntilFinished == 0L) {
                mIsTiming = false
                mBinding.verifyTime.text = StringUtils.getString(string.verify_again)
                mBinding.verifyTime.alpha = 1.0F
            } else {
                mIsTiming = true
                val nowTime = millisUntilFinished / 1000
                if (nowTime < 50 && !mIsInput) {
                    if (!mIsPlay) {
                        mBinding.selectGoogleLogin.play()
                        mIsPlay = true
                    }
                }
                mBinding.verifyTime.alpha = 0.3F
                mBinding.verifyTime.text = "${StringUtils.getString(string.verify_again)}(${nowTime}s)"
            }
        }

        mViewModel.verifyLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mViewModel.countdown()

                CacheUtil.saveVerifyCode(resolveCurrentNumber(), getSendType())
            }, {
                ToastGravity.showGravity(it.errorMsg)
            })
        }

        mViewModel.userResp.observe(this) { resultState ->
            parseState(resultState, {
                CacheUtil.deleteVerifyCode(resolveCurrentNumber(), getSendType())

                if (it.registered == true) {
                    Firebase.analytics.postEvent(
                        EventConst.SUCCESS_REGISTER,
                        bundleOf("type" to "phone")
                    )
                }

                //登录成功
                saveSuccessPhoneNumber()
                UserUtils.loginSuccess(it)

                startActivity(Intent(this, MainActivity::class.java))
                finish()
            }, {
                execAnim()
                ToastGravity.showGravity(it.errorMsg)
            })
        }

        mViewModel.bindPhoneLiveData.observe(this) { resultState ->
            parseState(resultState, {
                CacheUtil.deleteVerifyCode(resolveCurrentNumber(), getSendType())

                if (getSendType() == AppConst.LoginType.BIND) {
                    DomainManager.quickLoginWithAsync()
                }

                //绑定成功
                EventBus.getDefault().post(EventMessage(BizEventConst.BIND_SUCCESS))
                EventBus.getDefault().post(EventMessage(BizEventConst.INFO_UPDATA))
                finish()
            }, {
                execAnim()
                ToastGravity.showGravity(it.errorMsg)
            })
        }
    }

    private fun execAnim() {
        mBinding.etNumberOne.setBackgroundResource(R.drawable.frame_red_circular)
        mBinding.etNumberTwo.setBackgroundResource(R.drawable.frame_red_circular)
        mBinding.etNumberThree.setBackgroundResource(R.drawable.frame_red_circular)
        mBinding.etNumberFour.setBackgroundResource(R.drawable.frame_red_circular)

        mBinding.etNumberOne.setTextColor(ColorUtils.getColor(R.color.fe1849))
        mBinding.etNumberTwo.setTextColor(ColorUtils.getColor(R.color.fe1849))
        mBinding.etNumberThree.setTextColor(ColorUtils.getColor(R.color.fe1849))
        mBinding.etNumberFour.setTextColor(ColorUtils.getColor(R.color.fe1849))
    }

    private fun verifyEdit() {
        mBinding.etNumberOne.inputType = EditorInfo.TYPE_CLASS_NUMBER
        mBinding.etNumberTwo.inputType = EditorInfo.TYPE_CLASS_NUMBER
        mBinding.etNumberThree.inputType = EditorInfo.TYPE_CLASS_NUMBER
        mBinding.etNumberFour.inputType = EditorInfo.TYPE_CLASS_NUMBER
        mBinding.etNumberOne.isFocusableInTouchMode = true
        mBinding.etNumberTwo.isFocusableInTouchMode = true
        mBinding.etNumberThree.isFocusableInTouchMode = true
        mBinding.etNumberFour.isFocusableInTouchMode = true
        mBinding.etNumberOne.isFocusable = true
        mBinding.etNumberOne.requestFocus()
        //显示软键盘
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)

        //addTextChangedListener设置监听文本变化，有输入跳转到下一个输入框
        mBinding.etNumberOne.addTextChangedListener(
            TextChangeLister(
                mBinding.etNumberOne,
                mBinding.etNumberTwo
            )
        )
        //setOnKeyListener设置监听键盘删除操作，删除完之后跳转到上一个输入框
        mBinding.etNumberTwo.setOnKeyListener(
            MyOnKeyListener(
                mBinding.etNumberOne,
                mBinding.etNumberTwo
            )
        )
        mBinding.etNumberTwo.addTextChangedListener(
            TextChangeLister(
                mBinding.etNumberTwo,
                mBinding.etNumberThree
            )
        )
        mBinding.etNumberThree.setOnKeyListener(
            MyOnKeyListener(
                mBinding.etNumberTwo,
                mBinding.etNumberThree
            )
        )
        mBinding.etNumberThree.addTextChangedListener(
            TextChangeLister(
                mBinding.etNumberThree,
                mBinding.etNumberFour
            )
        )
        mBinding.etNumberFour.setOnKeyListener(
            MyOnKeyListener(
                mBinding.etNumberThree,
                mBinding.etNumberFour
            )
        )
        mBinding.etNumberFour.addTextChangedListener(object : TextWatcherAdapter() {
            override fun afterTextChanged(s: Editable?) {
                mBinding.etNumberOne.setBackgroundResource(R.drawable.verify_edit_common_back)
                mBinding.etNumberTwo.setBackgroundResource(R.drawable.verify_edit_common_back)
                mBinding.etNumberThree.setBackgroundResource(R.drawable.verify_edit_common_back)
                mBinding.etNumberFour.setBackgroundResource(R.drawable.verify_edit_common_back)

                mBinding.etNumberOne.setTextColor(ColorUtils.getColor(R.color.f202028))
                mBinding.etNumberTwo.setTextColor(ColorUtils.getColor(R.color.f202028))
                mBinding.etNumberThree.setTextColor(ColorUtils.getColor(R.color.f202028))
                mBinding.etNumberFour.setTextColor(ColorUtils.getColor(R.color.f202028))

                triggerLogin()
                setInputBack()
            }
        })
    }

    private fun triggerLogin() {
        val s1 = mBinding.etNumberOne.text.toString()
        val s2 = mBinding.etNumberTwo.text.toString()
        val s3 = mBinding.etNumberThree.text.toString()
        val s4 = mBinding.etNumberFour.text.toString()
        if (s1.isNotEmpty() && s2.isNotEmpty() && s3.isNotEmpty() && s4.isNotEmpty()) {
            val verify = s1 + s2 + s3 + s4
            goLogin(verify)
        }
    }

    private fun goLogin(verify: String) {
        val gmail = mGmail
        if (!gmail.isNullOrEmpty()) {
            if (mIsBind) {
                mViewModel.bindGmail(gmail, verify)
            } else {
                mViewModel.goGmailLogin(gmail, verify)
            }
        } else {
            val areaCode = mAreaCode
            val phoneNumber = mPhoneNumber
            if (areaCode.isNullOrEmpty() || phoneNumber.isNullOrEmpty()) {
                ToastGravity.showGravity(string.error_data)
                return
            }
            if (mIsBind) {
                mViewModel.bindPhone(areaCode, phoneNumber, verify)
            } else {
                mViewModel.goPhoneLogin(areaCode, phoneNumber, verify)
            }
        }
    }

    private fun sendVerifyCode(timeInMillis: Long? = null) {
        if (timeInMillis != null && timeInMillis > 0) {
            mViewModel.countdown(timeInMillis)
            return
        }

        val sendType = getSendType()

        val gmail = mGmail
        if (!gmail.isNullOrEmpty()) {
            if (mGoogleValidate != null) {
                mViewModel.sendGmailVerify(timeInMillis != null, gmail, mGoogleValidate, sendType)
                mGoogleValidate = null
            } else {
                verifyGoogle {
                    mViewModel.sendGmailVerify(timeInMillis != null, gmail, it, sendType)
                }
            }
        } else {
            val areaCode = mAreaCode
            val phoneNumber = mPhoneNumber
            if (!areaCode.isNullOrEmpty() && !phoneNumber.isNullOrEmpty()) {
                if (mGoogleValidate != null) {
                    mViewModel.sendPhoneVerify(timeInMillis != null, areaCode, phoneNumber, mGoogleValidate, sendType)
                    mGoogleValidate = null
                } else {
                    verifyGoogle {
                        mViewModel.sendPhoneVerify(timeInMillis != null, areaCode, phoneNumber, it, sendType)
                    }
                }
            }
        }
    }

    private fun resolveCurrentNumber(): String {
        val gmail = mGmail
        return if (!gmail.isNullOrEmpty()) {
            CommonUtils.resolveGmail(gmail) ?: ""
        } else {
            "+$mAreaCode $mPhoneNumber"
        }
    }

    private fun getSendType(): Int {
        return if (mIsBind) {
            AppConst.LoginType.BIND
        } else {
            AppConst.LoginType.REGISTERED
        }
    }

    private fun saveSuccessPhoneNumber() {
        if (mIsBind) {
            return
        }

        val areaCode = mAreaCode
        val phoneNumber = mPhoneNumber
        if (areaCode != null && phoneNumber != null) {
            CacheUtil.saveLastAreaCodeAndPhoneNumber(areaCode, phoneNumber)
        }
        val gmail = mGmail
        if (gmail != null) {
            CacheUtil.saveLastGmail(gmail)
        }
    }

    //自定义键盘监听
    private inner class MyOnKeyListener(
        private val upDt: EditText,
        private val thisDt: EditText,
    ) : View.OnKeyListener {

        override fun onKey(view: View, i: Int, keyEvent: KeyEvent): Boolean {
            if (keyEvent.action == KeyEvent.ACTION_DOWN && i == KeyEvent.KEYCODE_DEL) {
                if (thisDt.text.toString().isEmpty()) { //如果上一个输入框不为空
                    upDt.isFocusable = true
                    upDt.isFocusableInTouchMode = true
                    upDt.requestFocus()
                    upDt.setText("")
                }
                return false
            }
            return false
        }
    }

    //自定义文本变化监听类
    private inner class TextChangeLister(
        private val thisEt: EditText,
        private val newEt: EditText,
    ) : TextWatcherAdapter() {

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            if (before == 0 && count == 1) {
                thisEt.clearFocus()
                newEt.requestFocus()
            }
        }

        override fun afterTextChanged(s: Editable?) {
            mIsInput = true
            val s4 = mBinding.etNumberFour.text.toString()
            val s1 = mBinding.etNumberOne.text.toString()
            val s2 = mBinding.etNumberTwo.text.toString()
            val s3 = mBinding.etNumberThree.text.toString()
            val verify = s1 + s2 + s3 + s4
            if (verify.length == 4) {
                goLogin(verify)
            } else {
                mBinding.etNumberOne.setBackgroundResource(R.drawable.verify_edit_common_back)
                mBinding.etNumberTwo.setBackgroundResource(R.drawable.verify_edit_common_back)
                mBinding.etNumberThree.setBackgroundResource(R.drawable.verify_edit_common_back)
                mBinding.etNumberFour.setBackgroundResource(R.drawable.verify_edit_common_back)

                mBinding.etNumberOne.setTextColor(ColorUtils.getColor(R.color.f202028))
                mBinding.etNumberTwo.setTextColor(ColorUtils.getColor(R.color.f202028))
                mBinding.etNumberThree.setTextColor(ColorUtils.getColor(R.color.f202028))
                mBinding.etNumberFour.setTextColor(ColorUtils.getColor(R.color.f202028))
                setInputBack()
            }
        }
    }

    private fun setInputBack() {
        if (mBinding.etNumberOne.hasFocus()) {
            mBinding.etNumberOne.setBackgroundResource(R.drawable.verify_edit_input_back)
        }
        if (mBinding.etNumberTwo.hasFocus()) {
            mBinding.etNumberTwo.setBackgroundResource(R.drawable.verify_edit_input_back)
        }
        if (mBinding.etNumberThree.hasFocus()) {
            mBinding.etNumberThree.setBackgroundResource(R.drawable.verify_edit_input_back)
        }
        if (mBinding.etNumberFour.hasFocus()) {
            mBinding.etNumberFour.setBackgroundResource(R.drawable.verify_edit_input_back)
        }
    }
}